package com.audaque.springboot.foshanupload.core.component;

/**
 * @author zgb
 * @desc ...
 * @date 2021-12-25 00:12:04
 */


import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

/**
 * 获取Spring上下文对象
 * ========================
 * Created with IntelliJ IDEA.
 * User：恒宇少年
 * Date：2017/8/26
 * Time：23:25
 * 码云：http://git.oschina.net/jnyqy
 * ========================
 */
@Slf4j
@Component
public class ApplicationContextProvider implements InitializingBean {
    /**
     * 上下文对象实例
     */
    @Autowired
    private ApplicationContext applicationContext;


    /**
     * 获取applicationContext
     *
     * @return
     */
    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * 获取BeanFactory
     *
     * @return
     */
    public DefaultListableBeanFactory getDefaultListableBeanFactory() {
        return (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
    }

    public void destroySingleton() {
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
        //销毁指定实例 objectMapper是上文注解过的实例名称 name="objectMapper" 或没注解情况下默认的bean名称
        defaultListableBeanFactory.destroySingleton("objectMapper");
    }

    public void registerSingleton(String beanName, Object singletonObject) {
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
        //重新注册同名实例，这样在其他地方注入的实例还是同一个名称，但是实例内容已经重新加载
        defaultListableBeanFactory.registerSingleton(beanName, singletonObject);
    }


    /**
     * 通过name获取 Bean.
     *
     * @param name
     * @return
     */
    public Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    /**
     * 通过class获取Bean.
     *
     * @param clazz
     * @param <T>
     * @return
     */
    public <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    /**
     * 通过name,以及Clazz返回指定的Bean
     *
     * @param name
     * @param clazz
     * @param <T>
     * @return
     */
    public <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }

    /**
     * 打印IOC容器中所有的Bean名称
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        log.debug(">>>>>>" + "打印IOC容器中所有的Bean名称");
        String[] names = applicationContext.getBeanDefinitionNames();
        for (String name : names) {
            log.debug(">>>>>>" + name);
            Object bean = null;
            try {
                bean = applicationContext.getBean(name);
            } catch (Exception e) {
                log.warn(e.getMessage());
            }
            //log.debug(">>>>>>" + bean);
        }
        log.debug("------\nBean 总计:" + applicationContext.getBeanDefinitionCount());
    }


}
